
package com.idealighter.game.games.zjh.struct;

import com.idealighter.game.games.common.AbstractTable;
import com.idealighter.game.games.zjh.dto.BillInfo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * 炸金花桌子 .
 * 
 * @date 2016年6月23日 上午11:27:46
 *
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class ZjhTable extends AbstractTable {

  // 座位数量
  private static final int SEAT_NUM = 5;

  private final ZjhRoom room;
  private final List<ZjhSeat> seats;
  // 一副牌
  private final List<ZjhCard> cards = Arrays.asList(ZjhCard.values());

  // 桌子是否准备完成
  private boolean readied = false;
  // 锅底：每副牌玩家所有下注之和(包括比牌的)
  private long totalBetChips;

  // 上一家是否暗注
  private boolean preDark = false;
  // 上一家下注(如果是比牌除以2)
  private long preBet;
  // 下一个操作seat
  private ZjhSeat nextOptSeat;
  // 赢家
  private ZjhSeat winner;
  // 最大牌
  private ZjhCards maxCards;

  // 游戏结算信息
  private Map<Long, BillInfo> billInfos = new HashMap<>();

  /**
   * 构造函数 .
   * 
   * @param id .
   * @param room .
   */
  public ZjhTable(int id, ZjhRoom room) {
    super(id);
    this.room = room;
    this.seats = createSeats();
  }

  /**
   * 创建位置.
   * 
   * @return
   */
  private List<ZjhSeat> createSeats() {
    List<ZjhSeat> seats = new ArrayList<>(SEAT_NUM);
    for (int i = 0; i < SEAT_NUM; i++) {
      seats.add(new ZjhSeat(i, this));
    }

    return Collections.unmodifiableList(seats);
  }

  /**
   * 游戏是否结束 .
   * 
   * @return
   */
  public boolean gameOver() {

    return winner() != null;
  }

  /**
   * 赢家,游戏结束才能确定赢家,只有一个赢家 .
   * 
   * @return
   */
  public ZjhSeat winner() {
    if (winner != null) {
      return winner;
    } else {
      ZjhSeat winnerTmp = null;
      for (ZjhSeat s : seats) {
        if (s.getPlayerId() > 0 && !s.isOver()) {
          if (winnerTmp != null) {
            return null;
          }

          winnerTmp = s;
        }
      }

      return winner = winnerTmp;
    }

  }

  /**
   * 重置桌子 .
   */
  public void reset() {
    this.readied = false;
    this.totalBetChips = 0;
    this.preDark = false;
    this.preBet = 0;
    this.nextOptSeat = null;
    this.winner = null;
    this.maxCards = null;
    this.billInfos.clear();
  }

  /**
   * 随机一个seat .
   * 
   * @return
   */
  public ZjhSeat randomSeat() {
    ZjhSeat nextOptSeat = null;
    List<ZjhSeat> copySeats = new ArrayList<>(seats);
    Collections.shuffle(copySeats);

    for (ZjhSeat s : copySeats) {
      if (s.getPlayerId() > 0) {
        nextOptSeat = s;
        break;
      }
    }

    return nextOptSeat;
  }

  /**
   * 随机一个比牌的玩家 .
   * 
   * @return
   */
  public ZjhSeat randomVsSeat(ZjhSeat seat) {
    ZjhSeat vsSeat = null;
    List<ZjhSeat> copySeats = new ArrayList<>(seats);
    Collections.shuffle(copySeats);

    for (ZjhSeat s : copySeats) {
      if (s.getPlayerId() > 0 && !s.isOver() && s.getPlayerId() != seat.getPlayerId()) {
        vsSeat = s;
        break;
      }
    }

    return vsSeat;
  }

  /**
   * 下一个操作seat .
   * 
   * @param seat 座位信息.
   * @return
   */
  public ZjhSeat nextOptSeat(ZjhSeat seat) {
    int nextOptOrder = seat.getOrder();

    for (;;) {
      nextOptOrder = ++nextOptOrder % SEAT_NUM;

      if (nextOptOrder == seat.getOrder()) {
        return null;
      } else {
        ZjhSeat nextOptSeat = getSeat(nextOptOrder);
        if (nextOptSeat.getPlayerId() > 0 && !nextOptSeat.isOver()) {
          return nextOptSeat;
        }
      }
    }
  }


  /**
   * 获取seat .
   * 
   * @param order .
   * @return
   */
  public ZjhSeat getSeat(int order) {

    return seats.get(order);
  }

  @SuppressWarnings("unchecked")
  @Override
  public ZjhRoom room() {
    return room;
  }

  @Override
  public List<ZjhSeat> seats() {

    return seats;
  }

}
